/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game.experts.combine;

import analysys.HECAlignment;
import analysys.HECAlignmentHit;
import game.datahandling.IOData;
import game.datahandling.dataenvelopes.Data;
import game.datahandling.dataenvelopes.HECProtein;
import game.datahandling.dataenvelopes.base.PrimaryStructure;
import game.encodings.OutputEncoding;
import java.util.ArrayList;
import java.util.List;
import org.python.core.PyFloat;
import org.python.util.PythonInterpreter;

/**
 *
 * @author emanuele
 */
public abstract class SSPBaseHintedCombinerExpert extends HomogeneousCombinerExpert<PrimaryStructure> {
    public String weightExpression = "exp(2.0/er)";

    protected class CurrentInfo {
        PrimaryStructure input;
        List<HECAlignmentHit> hints;
    }

    public int maxhints = 3;
    public double minevalueth = 0;
    public double maxevalueth = 1e-2;
    
    protected CurrentInfo current = null;

    @Override
    public OutputEncoding predict(PrimaryStructure input) {
        if (this.current == null) {
            this.current = new CurrentInfo();
        }
        this.current.input = input;
        this.current.hints = this.getAlignmentHints(input.toString());

        return super.predict(input);
    }

    @Override
    public double getCompetence(PrimaryStructure d) {
        return 1.0;
    }

    List<HECAlignmentHit> getAlignmentHints(String input) {
        List<HECAlignmentHit> ret = new ArrayList<HECAlignmentHit>();

        HECAlignment al = new HECAlignment(new HECProtein(input), this.maxevalueth);

        for (int i = 0; i < al.size() && ret.size() < this.maxhints; i++) {
            HECAlignmentHit hint = al.get(i);
            if (hint.evalue >= this.minevalueth) {
                ret.add(hint);
            }
        }

        return ret;
    }

    public boolean canPredict(IOData<PrimaryStructure, Data> data) {
        return true; // TODO
    }

    protected int getDifferences(String a, String b) {
        assert a.length() == b.length();

        int ret = 0;
        for (int i = 0; i < a.length(); i++) {
            if (a.charAt(i) != b.charAt(i)) {
                ret++;
            }
        }
        return ret;
    }

    protected int getDifferences(String a, String b, int start, int end) {
        assert a.length() == b.length();
        assert start >= 0;
        assert end <= a.length();

        int ret = 0;
        for (int i = start; i < end; i++) {
            if (a.charAt(i) != b.charAt(i)) {
                ret++;
            }
        }
        return ret;
    }

    protected double weightFromErrorRate(double errorRate) {
        PythonInterpreter p = new PythonInterpreter();
        p.exec("from math import *");
        p.set("er", new PyFloat(errorRate));
        p.exec("weight = " + this.weightExpression);
        
        return p.get("weight", Double.class);
    }
}
